package itdep.jsf.internal;

import javax.faces.component.UIData;
import javax.faces.model.DataModel;
import javax.faces.model.SelectItem;
import java.util.ArrayList;
import java.util.List;

/**
 * Edited: 16.04.2009$ 14:04:41$ by Tolar
 */
public abstract class BaseTableBean<E> {
	protected final static Integer[] RESULTS_PER_PAGE_LOOKUP = {10, 20, 30};

	private SortableDataProvider<E> dataProvider;
	private DataModel dataModel; //todo: add default initialization

	private String listOutcome;
	private String editOutcome;
	private E record;
	private UIData tableBinding;
	private int resultsPerPage = 10;
	private int currentPage = 1;

	public UIData getTableBinding() {
		return tableBinding;
	}

	public void setTableBinding(UIData tableBinding) {
		this.tableBinding = tableBinding;
	}

	public DataModel getDataModel() {
		return dataModel;
	}

	public void setDataModel(DataModel dataModel) {
		this.dataModel = dataModel;
	}

	public SortableDataProvider<E> getDataProvider() {
		return dataProvider;
	}

	public void setDataProvider(SortableDataProvider<E> dataProvider) {
		this.dataProvider = dataProvider;
		setDataModel(new ScrollableDataModel<E>(dataProvider));
	}

	public String getOutcome() {
		return listOutcome;
	}

	public void setOutcome(String listOutcome) {
		this.listOutcome = listOutcome;
	}

	public String getEditOutcome() {
		return (editOutcome != null) ? editOutcome : getOutcome();
	}

	public void setEditOutcome(String editOutcome) {
		this.editOutcome = editOutcome;
	}

	public E getRecord() {
		return record;
	}

	private void setRecord(E record) {
		this.record = record;
	}

	public int getResultsPerPage() {
		return resultsPerPage;
	}

	public void setResultsPerPage(int resultsPerPage) {
		this.resultsPerPage = resultsPerPage;
		int lastPage = getLastPage();
		if (currentPage > lastPage) {
			this.currentPage = lastPage;
		}
	}

	private int getLastPage() {
		final int rowCount = dataProvider.getRowCount();
		return rowCount == 0 ? 1 :
				rowCount / resultsPerPage + (rowCount % resultsPerPage == 0 ? 0 : 1);
	}

	public int getCurrentPage() {
		return currentPage;
	}

	public void setCurrentPage(int currentPage) {
		this.currentPage = currentPage;
	}

	public String add() {
		setRecord(addMethod());
		return getEditOutcome();
	}

	public String edit() {
		setRecord(editMethod(getCurrentRecord()));
		return getEditOutcome();
	}

	public String delete() {
		setRecord(deleteMethod(getCurrentRecord()));
		return getOutcome();
	}

	public String save() {
		if (isEditMode()) {
			setRecord(saveMethod(getRecord()));
		}
		return getOutcome();
	}

	public String cancel() {
		setRecord(cancelMethod(getRecord()));
		return getOutcome();
	}

	protected E addMethod() {
		return null;
	}

	protected E editMethod(E record) {
		return record;
	}

	protected E saveMethod(E record) {
		return null;
	}

	protected E deleteMethod(E record) {
		return null;
	}

	protected E cancelMethod(E record) {
		return null;
	}

	@SuppressWarnings({"unchecked"})
	protected E getCurrentRecord() {
		return (getTableBinding().isRowAvailable() ? (E) getTableBinding().getRowData() : null);
	}

	public boolean isEditMode() {
		return (getRecord() != null);
	}

	@Deprecated
	public boolean isResultsPerPageLookupVisible() {
		return (getResultsPerPage() < dataProvider.getRowCount());
	}

	@Deprecated
	public List<SelectItem> getResultsPerPageLookup() {
		List<SelectItem> results = new ArrayList<SelectItem>();

		for (Integer item : RESULTS_PER_PAGE_LOOKUP) {
			results.add(new SelectItem(item, item.toString()));
		}

		return results;
	}
}
